package org.ithasu.tools.net;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;

import org.ithasu.tools.Console;
import org.ithasu.tools.data.EntityProvider;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.json.simple.parser.JSONParser;

public class JSONTools {

	protected JSONTools() {
	}

	// -- Load ----------------------------------------

	private static JSONParser _parser = null;

	public static <O> O load(Class<O> expectedClass, String filename) {
		// -- Init parser --
		if (_parser == null) {
			_parser = new JSONParser();
		}
		_parser.reset();

		// -- Open file --
		File f = new File(filename);
		if (!f.exists()) {
			Console.error(new FileNotFoundException(filename));
			return null;
		}

		try {
			FileReader reader = new FileReader(f);
			return safeCast(expectedClass, _parser.parse(reader));
		} catch (Exception e) {
			Console.error(e);
			return null;
		}
	}

	public static String toString(Object object) {
		return JSONValue.toJSONString(object);
	}

	// -- General ----------------------------------------

	@SuppressWarnings("unchecked")
	public static <O> O safeCast(Class<O> expectedClass, Object o) {
		if (o != null && expectedClass.isInstance(o)) {
			return (O) o;
		} else {
			return null;
		}
	}

	// -- Object ----------------------------------------

	public static <O> O getProperty(Class<O> expectedClass, JSONObject object,
			String property) {
		return safeCast(expectedClass, object.get(property));
	}

	public static <O> O getProperty(Class<O> expectedClass, JSONObject object,
			String property, O defaultValue) {
		O value = getProperty(expectedClass, object, property);
		return (value == null) ? defaultValue : value;
	}

	// -- Interface ----------------------------------------

	/** Just here to know all entities that are JSON compatible */
	public interface JSONEntity {

		/** Create JSONObject from object */
		public JSONObject toJSON(JSONContext context);

		/** Load properties from object */
		public void parseJSON(JSONContext context, JSONObject o);

	}

	public static interface JSONContext {

		public EntityProvider<?> getEntityProvider(String name);

		public String getEntityProviderId(EntityProvider<?> provider);

	}

}
